<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
require_once('wanpitu/alimage.class.class.php');


class Alibaba_image {


    public $max_size = 0;
    public $max_width = 0;
    public $max_height = 0;
    public $min_width = 0;
    public $min_height = 0;
    public $max_filename = 0;
    public $max_filename_increment = 100;
    public $allowed_types = '';
    public $file_temp = '';
    public $file_name = '';
    public $orig_name = '';
    public $file_type = '';
    public $file_size = NULL;
    public $file_ext = '';
    protected $_mimes = array();
    public $xss_clean = FALSE;
    public $error_msg = array();
    public $file_path = '';

	private $config;
    private $namespace;
    private $dir;

    public function __construct($namespace = 'xueba',$dir = '/'){
        $this->_mimes =& get_mimes();
        $this->_CI = &get_instance();
        $this->_CI->load->config('upload_images');
        $this->config = $this->_CI->config->item('wanpitu');
        $this->namespace = $namespace;
        $this->dir = '/';
    }
    public function init($config){
        foreach($config as $key => $val){
            $this->set($key,$val);
        }
    }

    private function set($key, $val){
        $key = strtolower($key);
        if( array_key_exists( $key, get_class_vars(get_class($this) ) ) ){
            $this->setOption($key, $val);
        }
        return $this;
    }

    private function setOption($key, $val) {
        $this->$key = $val;
    }

    function do_upload($user_id,$file_name,$source_file){
        $image  = new AlibabaImage($this->config['ak'], $this->config['sk'], "TOP");
        $uploadPolicy = new uploadPolicy();
        $uploadPolicy->dir = $user_id;    //
        $uploadPolicy->name = $file_name;  // 文件名不/"
        if(!$image->existsFolder($this->namespace,$user_id)){
            $image->createDir($this->namespace,$user_id);
        }
        $uploadPolicy->namespace= $this->namespace;
        $res = $image->upload($source_file, $uploadPolicy, $opts = array());
        return $res;
    }

    function check_file($field='userfile'){
        $_file = null;
        if (isset($_FILES[$field]))
        {
            $_file = $_FILES[$field];
        }
        elseif (($c = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $field, $matches)) > 1)
        {
            $_file = $_FILES;
            for ($i = 0; $i < $c; $i++)
            {

                if (($field = trim($matches[0][$i], '[]')) === '' OR ! isset($_file[$field]))
                {
                    $_file = NULL;
                    break;
                }

                $_file = $_file[$field];
            }
        }

        if ( ! isset($_file))
        {
            $this->set_error('upload_no_file_selected', 'debug');
            return FALSE;
        }
        if ( ! is_uploaded_file($_file['tmp_name']))
        {
            $error = isset($_file['error']) ? $_file['error'] : 4;

            switch ($error)
            {
                case UPLOAD_ERR_INI_SIZE:
                    $this->set_error('upload_file_exceeds_limit', 'info');
                    break;
                case UPLOAD_ERR_FORM_SIZE:
                    $this->set_error('upload_file_exceeds_form_limit', 'info');
                    break;
                case UPLOAD_ERR_PARTIAL:
                    $this->set_error('upload_file_partial', 'debug');
                    break;
                case UPLOAD_ERR_NO_FILE:
                    $this->set_error('upload_no_file_selected', 'debug');
                    break;
                case UPLOAD_ERR_NO_TMP_DIR:
                    $this->set_error('upload_no_temp_directory', 'error');
                    break;
                case UPLOAD_ERR_CANT_WRITE:
                    $this->set_error('upload_unable_to_write_file', 'error');
                    break;
                case UPLOAD_ERR_EXTENSION:
                    $this->set_error('upload_stopped_by_extension', 'debug');
                    break;
                default:
                    $this->set_error('upload_no_file_selected', 'debug');
                    break;
            }

            return FALSE;
        }
        $this->file_temp = $_file['tmp_name'];
        $this->file_size = $_file['size'];
        $this->_file_mime_type($_file);
        $this->file_type = preg_replace('/^(.+?);.*$/', '\\1', $this->file_type);
        $this->file_type = strtolower(trim(stripslashes($this->file_type), '"'));
        $this->file_name = $this->_prep_filename($_file['name']);
        $this->file_ext  = $this->get_extension($this->file_name);
        if ( ! $this->is_allowed_filetype())
        {
            $this->set_error('upload_invalid_filetype', 'debug');
            return FALSE;
        }



        if ($this->file_size > 0)
        {
            $this->file_size = round($this->file_size/1024, 2);
        }

        if ( ! $this->is_allowed_filesize())
        {
            $this->set_error('upload_invalid_filesize', 'info');
            return FALSE;
        }

        if ( ! $this->is_allowed_dimensions())
        {
            $this->set_error('upload_invalid_dimensions', 'info');
            return FALSE;
        }

        if ($this->xss_clean && $this->do_xss_clean() === FALSE)
        {
            $this->set_error('upload_unable_to_write_file', 'error');
            return FALSE;
        }
        return true;
    }

    public function set_error($msg, $log_level = 'error')
    {
        $this->_CI->lang->load('upload');

        is_array($msg) OR $msg = array($msg);
        foreach ($msg as $val)
        {
            $msg = ($this->_CI->lang->line($val) === FALSE) ? $val : $this->_CI->lang->line($val);
            $this->error_msg[] = $msg;
            log_message($log_level, $msg);
        }

        return $this;
    }

    public function is_allowed_filetype($ignore_mime = FALSE)
    {
        if ($this->allowed_types === '*')
        {
            return TRUE;
        }
        $this->allowed_types = explode('|',$this->allowed_types);

        if (empty($this->allowed_types) OR ! is_array($this->allowed_types))
        {
            $this->set_error('upload_no_file_types', 'debug');
            return FALSE;
        }

        $ext = strtolower(ltrim($this->file_ext, '.'));

        if ( ! in_array($ext, $this->allowed_types, TRUE))
        {
            return FALSE;
        }

        if (in_array($ext, array('gif', 'jpg', 'jpeg', 'jpe', 'png'), TRUE) && @getimagesize($this->file_temp) === FALSE)
        {
            return FALSE;
        }

        if ($ignore_mime === TRUE)
        {
            return TRUE;
        }

        if (isset($this->_mimes[$ext]))
        {
            return is_array($this->_mimes[$ext])
                ? in_array($this->file_type, $this->_mimes[$ext], TRUE)
                : ($this->_mimes[$ext] === $this->file_type);
        }

        return FALSE;
    }

    public function is_allowed_filesize()
    {
        return ($this->max_size === 0 OR $this->max_size > $this->file_size);
    }

    public function is_allowed_dimensions()
    {
        if ( ! $this->is_image())
        {
            return TRUE;
        }

        if (function_exists('getimagesize'))
        {
            $D = @getimagesize($this->file_temp);

            if ($this->max_width > 0 && $D[0] > $this->max_width)
            {
                return FALSE;
            }

            if ($this->max_height > 0 && $D[1] > $this->max_height)
            {
                return FALSE;
            }

            if ($this->min_width > 0 && $D[0] < $this->min_width)
            {
                return FALSE;
            }

            if ($this->min_height > 0 && $D[1] < $this->min_height)
            {
                return FALSE;
            }
        }

        return TRUE;
    }

    public function do_xss_clean()
    {
        $file = $this->file_temp;

        if (filesize($file) == 0)
        {
            return FALSE;
        }

        if (memory_get_usage() && ($memory_limit = ini_get('memory_limit')))
        {
            $memory_limit *= 1024 * 1024;
            $memory_limit = number_format(ceil(filesize($file) + $memory_limit), 0, '.', '');
            ini_set('memory_limit', $memory_limit);
        }

        if (function_exists('getimagesize') && @getimagesize($file) !== FALSE)
        {
            if (($file = @fopen($file, 'rb')) === FALSE) // "b" to force binary
            {
                return FALSE;
            }
            $opening_bytes = fread($file, 256);
            fclose($file);
            return ! preg_match('/<(a|body|head|html|img|plaintext|pre|script|table|title)[\s>]/i', $opening_bytes);
        }

        if (($data = @file_get_contents($file)) === FALSE)
        {
            return FALSE;
        }

        return $this->_CI->security->xss_clean($data, TRUE);
    }

    public function is_image()
    {
        $png_mimes  = array('image/x-png');
        $jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg');
        if (in_array($this->file_type, $png_mimes))
        {
            $this->file_type = 'image/png';
        }
        elseif (in_array($this->file_type, $jpeg_mimes))
        {
            $this->file_type = 'image/jpeg';
        }
        $img_mimes = array('image/gif',	'image/jpeg', 'image/png');
        return in_array($this->file_type, $img_mimes, TRUE);
    }

    public function get_extension($filename)
    {
        $x = explode('.', $filename);

        if (count($x) === 1)
        {
            return '';
        }

        $ext = strtolower(end($x));
        return '.'.$ext;
    }
    protected function _prep_filename($filename)
    {
        if ($this->allowed_types === '*' OR ($ext_pos = strrpos($filename, '.')) === FALSE)
        {
            return $filename;
        }

        $ext = substr($filename, $ext_pos);
        $filename = substr($filename, 0, $ext_pos);
        return str_replace('.', '_', $filename).$ext;
    }
    protected function _file_mime_type($file)
    {
        $regexp = '/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/';

        if (function_exists('finfo_file')) {
            $finfo = @finfo_open(FILEINFO_MIME);
            if (is_resource($finfo)) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system
            {
                $mime = @finfo_file($finfo, $file['tmp_name']);
                finfo_close($finfo);

                if (is_string($mime) && preg_match($regexp, $mime, $matches)) {
                    $this->file_type = $matches[1];
                    return;
                }
            }
        }
    }

}
